home *** CD-ROM | disk | FTP | other *** search
- /*
-
- VAT packet interconversion routines
-
- */
-
- #include "speakfree.h"
- #include "vat.h"
- #include <pwd.h>
- #include <sys/param.h>
-
- static audio_descr_t adt[] = {
- /* enc sample ch */
- {AE_PCMU, 8000, 1}, /* 0 PCMU */
- {AE_MAX, 8000, 1}, /* 1 1016 */
- {AE_MAX, 0, 1}, /* 2 G721 32 kb/s CCITT ADPCM */
- {AE_GSM, 8000, 1}, /* 3 GSM */
- {AE_MAX, 0, 1}, /* 4 G723 24 kb/s CCITT ADPCM */
- {AE_MAX, 0, 1}, /* 5 unassigned */
- {AE_MAX, 0, 1}, /* 6 unassigned */
- {AE_MAX, 0, 1}, /* 7 unassigned */
- {AE_MAX, 0, 1}, /* 8 unassigned */
- {AE_MAX, 0, 1}, /* 9 unassigned */
- {AE_MAX, 0, 1}, /* 10 unassigned */
- {AE_MAX, 0, 1}, /* 11 unassigned */
- {AE_MAX, 0, 1}, /* 12 unassigned */
- {AE_MAX, 0, 1}, /* 13 unassigned */
- {AE_MAX, 0, 1}, /* 14 unassigned */
- {AE_MAX, 0, 1}, /* 15 unassigned */
- {AE_MAX, 0, 1}, /* 16 unassigned */
- {AE_MAX, 0, 1}, /* 17 unassigned */
- {AE_MAX, 0, 1}, /* 18 unassigned */
- {AE_MAX, 0, 1}, /* 19 unassigned */
- {AE_MAX, 0, 1}, /* 20 unassigned */
- {AE_MAX, 0, 1}, /* 21 unassigned */
- {AE_MAX, 0, 1}, /* 22 unassigned */
- {AE_MAX, 0, 1}, /* 23 unassigned */
- {AE_MAX, 0, 1}, /* 24 unassigned */
- {AE_MAX, 0, 1}, /* 25 unassigned */
- {AE_MAX, 0, 1}, /* 26 L16, 16000 samples/sec */
- {AE_MAX, 0, 1}, /* 27 L16, 44100 samples/sec, 2 channels */
- {AE_LPC, 8000, 1}, /* 28 LPC, 4 frames */
- {AE_LPC, 8000, 1}, /* 29 LPC, 1 frame */
- {AE_IDVI, 8000, 1}, /* 30 32 kb/s Intel DVI ADPCM */
- {AE_MAX, 0, 1}, /* 31 unassigned */
- };
-
- /* ISVAT -- Determine if this is a parseable VAT format packet.
- If so, convert it to an equivalent sound buffer. */
-
- int isvat(pkt, len)
- unsigned char *pkt;
- int len;
- {
- int findex = pkt[1] & VATHF_FMTMASK;
- soundbuf *s = (soundbuf *) pkt;
-
- /* Validate (as much as possible) whether this is a VAT packet
- that we're able to translate. */
-
- if (((pkt[0] & 0xC0) == 0) && ((pkt[1] & 0x60) == 0) /* &&
- (adt[findex].encoding != AE_MAX) */
- ) {
-
- struct soundbuf sb;
- unsigned char *payload;
- int paylen;
-
- /*fprintf(stderr, "VAT Ver = %d, nsid = %d, ts = %d, format = %d confid = %d, tstamp = %ld\n",
- pkt[0] >> 6, pkt[0] & NSID_MASK, !!(pkt[1] & VATHF_NEWTS), findex,
- (((unsigned int) pkt[2]) << 8) | pkt[3],
- (((unsigned long) pkt[4]) << 24) |
- (((unsigned long) pkt[5]) << 16) |
- (((unsigned long) pkt[6]) << 8) |
- (((unsigned long) pkt[7]) << 0));
- */
-
- payload = pkt + (8 + 4 * (pkt[0] & NSID_MASK)); /* Payload start */
- paylen = len - ((8 + 4 * (pkt[0] & NSID_MASK))); /* Payload length */
- sb.compression = fProtocol;
- sb.buffer.buffer_len = 0;
-
- #ifdef NEEDED
- /* Fake a VAT unique host name from the conference identifier. */
-
- sprintf(sb.sendinghost, ".VAT:%02X%02X",
- pkt[2], pkt[3]);
- #else
- strcpy(sb.sendinghost, ".VAT");
- #endif
-
- switch (adt[findex].encoding) {
-
- case AE_PCMU:
- sb.buffer.buffer_len = paylen;
- bcopy(payload, sb.buffer.buffer_val, paylen);
- break;
-
- case AE_GSM:
- sb.buffer.buffer_len = paylen + sizeof(short);
- bcopy(payload, sb.buffer.buffer_val + 2, paylen);
- *((short *) sb.buffer.buffer_val) =
- htons((short) ((((long) paylen) * 160) / 33));
- sb.compression |= fCompGSM;
- break;
-
- case AE_IDVI:
- bcopy(payload + 4, sb.buffer.buffer_val, paylen - 4);
- bcopy(payload, sb.buffer.buffer_val + (paylen - 4), 3);
- sb.buffer.buffer_len = paylen - 1;
- if (adt[findex].sample_rate == 8000) {
- sb.compression |= fCompADPCM;
- } else {
- #ifdef NEEDED
-
- /* Bogus attempt to convert sampling rate. We
- really need to do this in linear mode, which isn't
- supported on all SPARCs. This is better than
- nothing, though. */
-
- int inc = adt[findex].sample_rate / 8000, i;
- unsigned char *in = (unsigned char *) sb.buffer.buffer_val,
- *out = (unsigned char *) sb.buffer.buffer_val;
-
- adpcmdecomp(&sb);
- for (i = 0; i < (paylen - 4) / inc; i++) {
- *out++ = *in;
- in += inc;
- }
- sb.buffer.buffer_len /= inc;
- #endif
- }
- break;
-
- case AE_LPC:
- sb.buffer.buffer_len = paylen + sizeof(short);
- { int i;
- unsigned char *in = payload,
- *out = (unsigned char *) sb.buffer.buffer_val + 2;
-
- for (i = 0; i < paylen / 14; i++) {
- bcopy(in, out, 3);
- out[3] = 0;
- bcopy(in + 3, out + 4, 10);
- in += 14;
- out += 14;
- }
- }
- *((short *) sb.buffer.buffer_val) =
- htons((short) ((((long) paylen) * LPC_FRAME_SIZE) / 14));
- sb.compression |= fCompLPC;
- break;
-
- case AE_L16:
- if (adt[findex].channels == 1) {
- int i, j, k;
-
- for (i = j = k = 0; i < (paylen / 8); i++) {
- if ((k & 3) != 2 && ((i % 580) != 579)) {
- sb.buffer.buffer_val[j++] =
- audio_s2u((((unsigned short *) payload)[i * 4]));
- }
- k = (k + 1) % 11;
- }
- sb.buffer.buffer_len = j;
- } else if (adt[findex].channels == 2) {
- int i, j, k;
-
- for (i = j = k = 0; i < (paylen / 16); i++) {
- if ((k & 3) != 2 && ((i % 580) != 579)) {
- sb.buffer.buffer_val[j++] =
- audio_s2u(((((unsigned short *) payload)[i * 8]) +
- (((unsigned short *) payload)[i * 8 + 1])) / 2);
- }
- k = (k + 1) % 11;
- }
- sb.buffer.buffer_len = j;
- }
- break;
-
- default:
- /* Unknown compression type. */
- sb.buffer.buffer_len = 0;
- break;
- }
- bcopy(&sb, pkt, (int) (((sizeof sb - BUFL)) + sb.buffer.buffer_len));
- return TRUE;
- }
- return FALSE;
- }
-
- /* VATOUT -- Convert a sound buffer into a VAT packet, given the
- timestamp for the next packet sent to this connection. */
-
- int vatout(sb, ssrc_i, timestamp_i, spurt)
- soundbuf *sb;
- unsigned long ssrc_i;
- unsigned long timestamp_i;
- int spurt;
- {
- soundbuf rp;
- char *pkt = (char *) &rp;
- LONG pl = 0;
-
- pkt[0] = 0;
-
- pkt[1] = spurt ? 0x80 : 0;
-
- pkt[2] = ssrc_i & 0xFF;
- pkt[3] = (ssrc_i >> 8) & 0xFF;
-
- *((long *) (pkt + 4)) = htonl(timestamp_i);
-
- if (sb->compression & fCompGSM) {
- pkt[1] |= VAT_AUDF_GSM;
- bcopy(sb->buffer.buffer_val + 2, pkt + 8,
- (int) sb->buffer.buffer_len - 2);
- pl = (sb->buffer.buffer_len - 2) + 8;
-
- } else if (sb->compression & fCompADPCM) {
- pkt[1] |= VAT_AUDF_IDVI;
- bcopy(sb->buffer.buffer_val, pkt + 8 + 4,
- (int) sb->buffer.buffer_len - 3);
- bcopy(sb->buffer.buffer_val + ((int) sb->buffer.buffer_len - 3),
- pkt + 8, 3);
- pkt[8 + 3] = 0;
- pl = (sb->buffer.buffer_len + 1) + 8;
-
- } else if (sb->compression & fCompLPC) {
- int n = (int) ((sb->buffer.buffer_len - 2) / 14);
- int i;
- char *cp = pkt + 8, *sp = sb->buffer.buffer_val + 2;
-
- pkt[1] |= VAT_AUDF_LPC4;
- pl = 8;
- for (i = 0; i < n; i++) {
- bcopy(sp, cp, 3);
- bcopy(sp + 4, cp + 3, 10);
- sp += 14;
- cp += 14;
- pl += 14;
- }
-
- } else { /* Uncompressed PCMU samples */
- #if (VAT_AUDF_MULAW8 != 0)
- pkt[1] |= VAT_AUDF_MULAW8;
- #endif
- bcopy(sb->buffer.buffer_val, pkt + 8,
- (int) sb->buffer.buffer_len);
- pl = (int) sb->buffer.buffer_len + 8;
- }
- if (pl > 0) {
- bcopy(pkt, (char *) sb, (int) pl);
- }
- return pl;
- }
-
- /* MAKEVATID -- Create VAT ID packet. */
-
- int makeVATid(vp, ssrc_i)
- char **vp;
- unsigned long ssrc_i;
- {
- char *sp = NULL, *cp = NULL;
- struct passwd *pw;
- char s[256];
- int l = 0;
-
- /* Watch as we make increasingly desperate attempts to
- obtain the user's full name. */
-
- sp = getenv("SPEAKFREE_ID");
- if (sp != NULL && strlen(sp) > 0) {
- char *ep = strchr(sp, ':');
- if (ep != NULL) {
- *ep = 0;
- }
- }
-
- if (sp == NULL) {
- pw = getpwuid(getuid());
- if (pw != NULL) {
- if (pw->pw_gecos != NULL) {
- strcpy(s, pw->pw_gecos);
- sp = s;
- } else if (pw->pw_name != NULL) {
- char hn[MAXHOSTNAMELEN];
-
- hn[0] = 0;
- gethostname(hn, sizeof hn);
- sprintf(s, "%s@%s", pw->pw_name, hn);
- sp = s;
- }
- }
- }
-
- if (sp == NULL) {
- if ((sp = getenv("SPEAKFREE_CNAME")) != NULL && strlen(sp) > 0) {
- if (sp[0] == '*') {
- sp++;
- }
- }
- }
-
- if (sp == NULL) {
- sp = "Unknown User";
- }
-
- cp = malloc(4 + strlen(sp) + 1);
- if (cp != NULL) {
- cp[0] = 0;
- cp[1] = 1;
- cp[2] = ssrc_i & 0xFF;
- cp[3] = (ssrc_i >> 8) & 0xFF;
- strcpy(cp + 4, sp);
- l = 4 + strlen(sp) + 1;
- }
- *vp = cp;
- return l;
- }
-
- /* MAKEVATDONE -- Create VAT "DONE" packet. */
-
- int makevatdone(v, ssrc_i)
- char *v;
- unsigned long ssrc_i;
- {
- v[0] = 0;
- v[1] = 2;
- v[2] = ssrc_i & 0xFF;
- v[3] = (ssrc_i >> 8) & 0xFF;
- return 4;
- }
-